import {TimeControllerOpt} from "../../controller/model/ControllerOpt";
import {TimeController} from "../../controller/TimeController";
import Configer from "../../frame/apiModel/config/Configer";
import {FinalKey} from "../../constant/FinalConstant";
import {ConfigKey, ResumeType} from "../../constant/ConfigConstant";
import {Util} from "../../utils/Util";
import {GlobalEnv} from "../../utils/GlobalEnv";
import {UnitAttribute, AttributeEnum} from "../../frame/dataSource/DataModel";
import {GuiController} from "../../controller/GuiController";
import {CaluAttrStr, SpecialEffectType} from "../../type/Type";
import {AbilityController} from "../../controller/AbilityController";
import {UnitController} from "../../controller/UnitController";
import {ModelFactory} from "../../frame/apiModel/adapterModel/model5/ModelFactory";
import {PlayerFactory} from "../../frame/PlayerFactory";
import {PlayerModel} from "../../frame/apiModel/adapterModel/model4/PlayerModel";
import {Logger} from "../../frame/apiModel/config/Logger";
import {UnitModel} from "../../frame/apiModel/adapterModel/model3/UnitModel";
import {GlobalModel} from "../../frame/apiModel/adapterModel/model1/GlobalModel";
import {CodeUtil} from "../../frame/codeAdapter/CodeUtil";
import {TextGuiKey} from "../../constant/UIConfig";
import {ResourceKey} from "../../constant/ResourceConstant";

export function poisonTrigger() {
    // 黑夜白天计时器
    const dayNightTurn = Configer.getConfig(ConfigKey.dayNightTurn);
    if (!CodeUtil.isNullOrZero(dayNightTurn)) {
    } else {
        return;
    }
    const resumeAllTime: number = Configer.getConfig(ConfigKey.resumeAllTime);
    const bossInterval: number = Configer.getConfig(ConfigKey.bossInterval);
    const resumeType = Configer.getConfig(ConfigKey.resumeTypes);
    let flog = 0;
    const startInNight = Configer.getConfig(ConfigKey.startInNight) as number;
    const timeOpenCallBack = () => {
        if (flog % 2 === startInNight) {
            GlobalModel.fog = false
            GlobalModel.mask = false;

            if (!CodeUtil.isNullOrZero(flog)) {
                GuiController.getInstance().showUiText(ResourceKey.toDay, true);
            }
            const timerOpt = new TimeControllerOpt('黑夜来临', timeOpenCallBack, 1);
            TimeController.getInstance().startTimer({time: resumeAllTime, opt: timerOpt});


            const allMap = Configer.getFinal(FinalKey.allMapRect);
            ModelFactory.getInstance().mapUnitInRect(allMap, (unit) => {
                const player = PlayerFactory.getInstance().getUnitOwner(unit);
                const playerCheck = player.isNotEndPlaying()
                if (playerCheck) {
                } else {
                    return;
                }
                UnitController.getInstance().addCaluAttributeTaskByUnit(unit, false, CaluAttrStr.poison);
            })
        } else {
            GlobalModel.fog = true
            GlobalModel.mask = true;

            if (resumeType === ResumeType.resumeAllInDay) {
                const calllBack = () => {
                    PlayerFactory.getInstance().mapAllNotEndPlayingPlayer((player: PlayerModel) => {
                        const hero = GlobalEnv.getHero(player);
                        if (hero) {
                            const isAlive = hero?.isAliveInBattle();
                            if (isAlive) {
                            } else {
                                const loc = player.startLocation;
                                hero.revive(loc, true)
                                player.moveUnit(hero, loc);
                                UnitController.getInstance().addCaluAttributeTaskByUnit(hero, false, CaluAttrStr.revert);
                            }
                        }
                    })
                }
                const timerOpt = new TimeControllerOpt('全体复活', calllBack, 1);
                TimeController.getInstance().startTimer({time: resumeAllTime, opt: timerOpt});
            }

            PlayerFactory.getInstance().mapAllNotEndPlayingPlayer((player: PlayerModel) => {
                Logger.toastProduct(`夜晚爆率提升`, player)
            });
            GuiController.getInstance().showUiText(ResourceKey.toNight, true);
            const timerOpt = new TimeControllerOpt('天亮了', timeOpenCallBack, 1);
            TimeController.getInstance().startTimer({time: resumeAllTime, opt: timerOpt});

            const bossBecomeFun = () => {
                GuiController.getInstance().showUiText(ResourceKey.bossBecome, true);
            }
            const bossBecomeOpt = new TimeControllerOpt(undefined, bossBecomeFun, 1);
            TimeController.getInstance().startTimer({time: bossInterval, opt: bossBecomeOpt});

            const poison = Configer.getConfig(ConfigKey.poison);
            if (!CodeUtil.isNullOrZero(poison)) {
                const poisonCallBack = function () {
                    const allMap = Configer.getFinal(FinalKey.allMapRect);
                    ModelFactory.getInstance().mapUnitInRect(allMap, (unit) => {
                        const player = PlayerFactory.getInstance().getUnitOwner(unit);
                        const playerCheck = player.isNotEndPlaying();
                        if (playerCheck) {
                        } else {
                            return;
                        }
                        UnitController.getInstance().addCaluAttributeTaskByUnit(unit, false, CaluAttrStr.poison);

                        let rect;
                        const safeRange = Configer.getFinal(FinalKey.safeRange) as string;
                        if (safeRange) {
                            rect = ModelFactory.getInstance().getRectModel(safeRange);
                        }

                        if (rect) {
                            const rangeCheck = ModelFactory.getInstance().rectContainsUnit(rect, unit);
                            if (rangeCheck) {
                                return;
                            }
                        }
                        poisonUnit(unit);
                    })

                }
                const poisonOpt = new TimeControllerOpt(undefined, poisonCallBack, resumeAllTime);
                TimeController.getInstance().startTimer({time: 1, opt: poisonOpt});
            }
        }
        flog = flog + 1;
    }
    timeOpenCallBack();
}

function poisonUnit(unit: UnitModel) {
    const isInvulnerable = unit.invulnerable;
    if (isInvulnerable) {
        return;
    }
    const poisonEffectPoint: string = Configer.getConfig(ConfigKey.poisonEffectPoint);
    const targetEffects: string = Configer.getConfig(ConfigKey.poisonEffect);
    TimeController.addSpecialEffectByResourceIdFun(unit, targetEffects, 1, undefined, poisonEffectPoint, SpecialEffectType.unit, 0)

    const wave = GlobalEnv.wave;
    const cardinal = Configer.getConfig(ConfigKey.poisonCardinal) as number;
    const divisor = Configer.getConfig(ConfigKey.poisonDivisor) as number;

    let hurt = getPoisonHurtByWave(wave, cardinal, divisor);
    const currentLife = unit.life;

    const maxLife = unit.maxLife;
    const usePercent = Configer.getConfig(ConfigKey.poisonUsePercent) as number;

    if (!CodeUtil.isNullOrZero(usePercent)) {
        const percentValue = hurt / 100;
        hurt = percentValue * maxLife;
    }

    const poisonEffect: string = Configer.getFinal(FinalKey.poisonEffect);
    AbilityController.getInstance().addAbilityAttributes(unit, poisonEffect, 1.1, new UnitAttribute());
    const leftLife = currentLife - hurt;
    if (leftLife > 0) {
        unit.life = leftLife;
    } else {
        unit.kill();
    }
}

function getPoisonHurtByWave(wave: number, cardinal: number, divisor: number) {
    const hurt = cardinal + (wave - 1) * divisor;
    return hurt;
}
